;;;primitives and means of combination
(define a (make-wire))
(define b (make-wire))
(define c (make-wire))
(define d (make-wire))
(define e (make-wire))
(define s (make-wire))
 
;;;inverter 非门
;;;and-gate 与门
;;;or-gate  或门
 
;;;或门输入为a和b，输出为d
(or-gate a b d)
(and-gate a b c)
(inverter c e)
(and-gate d e s)
 
;;;内部的dsl
;;;build up an invented language in Lisp, embedded
;;;外部的dsl
;;;
 
 
;;;means of abstraction
;;;a half adder
;;;输入a和b，输出和以及进位
(define (half-adder a b s e)
  (let ((d (make-wire))
        (e (make-wire)))
    (or-gate a b d)
    (and-gate a b c)
    (inverter c e)
    (and-gate d e s)))
 
;;;lambda：终极粘合剂
;;;lambda is the ultimate glue, if you will
 
;;;半加器可以用于构造更复杂的抽象结构
(define (full-adder a b c-in sum c-out)
  (let ((s (make-wire))
        (c1 (make-wire))
        (c2 (make-wire)))
    (half-adder b c-in s c1)
    (half-add a s sum c2)
    (or-gate c1 c2 c-out)))
 
;;;look at the primitives
;;;implementing a primitive
;;;非门
(define (inverter in out)
  (define (invert-in)
    (let ((new (logical-not (get-signal in))))
      (after-delay inverter-delay
                   (lambda ()
                     (set-signal! out new)))))
  (add-action! in invert-in))
 
(define (logical-not s)
  (cond ((= s 0) 1)
        ((= s 1) 0)
        (else (error "invalid signal" s))))
 
;;;与门
(define (and-gate a1 a2 output)
  ... )
 
;;;我们如何用"按愿望思维"来构造这一切呢
;;;now, how i implement these things is all wishful thinking
 
;;;
;;;-------a---->|
;;;             |
;;;             |与门 -----c----> 非门----d----->
;;;-------b---->|
;;;
;;;
 
;;;与门上有两根电线a和b，可以通过(get-signal a/b) (set-signal! a/b <new-value>)来获取或者修改电线上的值(也就是信号)
;;;即：询问电线上的信号
;;;非门也一样
 
 
;;;每一根电线都必须知道，自己承载的信号是什么，用变量signal表示。
;;;构造的电线，是一种可以接收消息的对象
;;;what's your method of adding action procedures?
;;;that it'll give me a procedure which is the add action procedure
;;;which i can then apply to an action procedure to create another action
;;;procedure in the wire.(也就是加入到电线的ap表中)
 
 
;;;the wire is the dispatch, returned by creating the wire,
;;;it's a procedure(******重点*******)
;;;i call that dispatch on the message get-signal
 
 
;;;agenda 议程
;;;the-agenda 用于组织时间和动作
;;;the-agenda 将记录执行动作的时刻
;;;current-time 加上delay的时刻
 
 
;;;事件驱动的模拟器
;;;event-driven simulation
 
;;;a way of organizing time
;;;agenda, 有时候又叫做优先队列
;;;which is an agenda or priority queue, it's sometimes called.
 
 
;;;agendas
(make-agenda) ---> new agenda
(current-time agenda) ---> time
(empty-agenda? agenda) ---> true/false
(add-to-agenda! time action agenda)
(first-item agenda) ---> action
(remove-first-item! agenda)
 
 
;;;---> *agenda* | --->  | ---> |/
;;;                     |
;;;                     v segment
;;;                  time| 
;;;                       |
;;;                       v
;;;                     queue
 
 
;;;queue
(make-queue)
(insert-queue! queue item)
(delete-queue! queue)
(front-queue queue)
(empty-queue? queue)
 
(set-car! <pair> <value>)
(set-cdr! <pair> <value>)
 
;;;identity
 
 
(define (cons x y)
  (lambda (m)
    (m x y)))
(define (car x)
  (x (lambda (a d)
       a)))
(define (cdr x)
  (x (lambda (a d)
       d)))
 
;;;"lambda calculus" mutable data
;;;cons是一个procedure，返回一个参数为m的procedure
(define (cons x y)
  (lambda (m) ;;;返回一个procedure
    (m x
       y
       (lambda (n) (set! x n))
       (lambda (n) (set! y n)))))
 
(define (car x)
  (x (lambda (a d sa sd) a)))
 
(define (cdr x)
  (x (lambda (a d sa sd) d)))
 
;;;其中x为cons，y为某个值
;;;(cons x y)返回一个procedure，参数为m
;;;参数m也是一个procedure，m的参数为4个
;;;第三个sa和第4个参数sd同样为一个procedure，参数为1个
(define (set-car! x y)
  (x (lambda (a d sa sd)
       (sa y))))
 
(define (set-cde! x y)
  (x (lambda (a d sa sd)
       (sd y))))
 
;;;总结：该数据是一个procedure，该procedure的参数也是一个procedure
;;;该参数的参数中也有procedure
 
 
;;;****************重点***************
;;;===================================================================================
;;;这是一个procedure，该procedure的参数中有procedure，参数的参数中也有procedure ... 递归下去
;;;procedure不停的跑到前面去，也就是(procedure ... ), (procedure ... ) ...
;;;也就是参数不停的跑到前面去
;;;===================================================================================
 
 
 
 
;;;permission to set x: (set! x n)
 
;;;
;;;
;;; ap表：action procedures
;;; 电线中包含：signal和ap表
;;; 电线a：<-----------------------
;;;     signal                   |
;;;     ap表:------              |a1指向电线a
;;;               |              |a1询问电线上的信号
;;;               |              |
;;;               |       与门：  |
;;;               |       |------|-----\                       |---------------------------------|
;;;               ------->|  a1--|      \                      v                                 |inoput指向电线c
;;;                       |              \  ------------>  电线c：                  非门：         |
;;;                       |        output/                      signal                 |---------|--------\
;;;              |------->|  a2--|      /                       ap表：----------------》| input---|         \
;;;              |        |------|-----/                                               |            output /
;;;              |               |                                                     |------------------/
;;; 电线b：       |               |
;;;  ^ signal    |               |a2指向电线b
;;;  | ap表:------               |
;;;  |                           |
;;;  |----------------------------
;;;
;;;
;;;
 
 
;;;与门上有两根电线a和b,可以通过(get-signal a/b) (set-signal! a/b <new-value>)来获取或者修改电线上的值(也就是信号)
;;;即:询问电线上的信号
;;;非门也一样
 
 
 
;;;
;;;事件驱动
;;;
;;;与非门通过get-signal等抽象函数获取电线上的信号
;;;===================================
;;;抽象层（构造函数，选择函数)
;;;===================================
;;;电线通过call-each，通知该电线上的与非门等
;;;
 
 
;;;总结：
;;;电线：包含signal和ap表
;;;     signal变化时，会通知与该电线关联的与非门（通过ap表进行关联）
;;;与非门：包含输入和输出
;;;      输入为电线，输出也是电线，可以获取到电线中的signal(通过get-signal等抽象函数获取)
;;;ap表：通过agenda实现